"""
    This file is part of Vondel.

    Vondel is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Vondel is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Vondel.  If not, see <http://www.gnu.org/licenses/>.
"""

import os
import xml.etree.ElementTree as etree
import time
from PyQt4.QtGui import QApplication

# Some constants for XML tag names.
XML_CHAPTER_COUNTER = 'chapterCounter'
XML_SCENE_COUNTER    = 'sceneCounter'
XML_CREATION_DATE    = 'creationDate'
XML_LAST_MODIFIED     = 'lastModified'
XML_BOOK                   = 'book'
XML_CHAPTER              = 'chapter'
XML_SCENE                 = 'scene'
XML_TITLE                  =  'title'
XML_VERSION              = 'version'
XML_AUTHOR               = 'author'
XML_ID                       = 'id'

class VondelBook(object):
    """
        Class for reading, writing and changing the Vondel XML file.

        Example of XML:
        Book
        +- Author
        +- Chapter 1
            - Scene 1
            - Scene 2
        +- Chapter 2
            - Scene 1
            - Scene 2
            - Scene 3
        +- Chapter counter
        +- Scenes counter
    """

    def __init__(self):
        """
            Constructor. Sort of.
        """
        self.FileName = ''
        book = etree.Element(XML_BOOK)
        self.book = etree.ElementTree(book)

    def Load(self,  FileName):
        """
            Load the XML file.
            @param FileName File name of the XML file.
        """
        self.FileName = FileName
        if os.path.exists(FileName):
            self.book.parse(FileName)
        else:
            # Create a new book.
            root = self.book.getroot()

            root.attrib[XML_TITLE] = QApplication.translate('New book', 'No Title')

            elem = etree.SubElement(root,  XML_VERSION)
            elem.text = '1'

            elem = etree.SubElement(root,  XML_AUTHOR)
            elem.text = XML_AUTHOR

            self.AddCreationDate(root)

            ch = self.AddChapter(QApplication.translate("New book", 'Chapter'))
            self.AddScene(ch,  QApplication.translate("New book", 'Scene'))
            self.AddScene(ch,  QApplication.translate("New book", 'Scene'))
            self.AddScene(ch,  QApplication.translate("New book", 'Scene'))
            self.AddScene(ch,  QApplication.translate("New book", 'Scene'))

            ch = self.AddChapter(QApplication.translate("New book", 'Chapter'))
            self.AddScene(ch,  QApplication.translate("New book", 'Scene'))
            self.AddScene(ch,  QApplication.translate("New book", 'Scene'))

            ch = self.AddChapter()
            self.AddScene(ch)
            self.AddScene(ch,  'àèìòù áéíóú äëïöü ñç')


    def Save(self):
        """
            Save the XML file.
        """
        self.__indent(self.book.getroot())
        self.book.write(self.FileName,  encoding="ISO-8859-1")

    def SaveAs(self,  FileName):
        """
            Save the XML with another name.

            @param FileName The new filename.
        """
        self.FileName = FileName
        self.Save()

    def __indent(self,  elem, level=0):
        """
            Private method to indent the XML layout.
        """
        i = "\n" + level*"  "
        if len(elem):
            if not elem.text or not elem.text.strip():
                elem.text = i + "  "
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
            for elem in elem:
                self.__indent(elem, level+1)
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
        else:
            if level and (not elem.tail or not elem.tail.strip()):
                elem.tail = i

    def AddCreationDate(self,  Node):
        """
            Add the timestamp of creation to the XML node.

            @param Node Node where to add timestamp to.
        """
        self.AddDate(Node,  XML_CREATION_DATE)

    def AddDate(self,  Node,  Text):
        """
            Add a timestamp.
        """
        #TODO: Check if element already exists.
        element = etree.SubElement(Node,  Text)
        element.text = time.ctime()

    def AddChapter(self,  Title = None):
        """
            Add a new chapter.attrib

            @param Title Optional title for the chapter.
        """
        root = self.book.getroot()
        chapter = etree.SubElement(root,  XML_CHAPTER)
        id = self.GetNextChapterId()
        chapter.attrib[XML_ID] = id

        # Chapter title. For translation sake it has to be done this way.
        if Title is None:  Title = QApplication.translate('New book', 'Chapter')
        chapter.attrib[XML_TITLE] = Title + ' ' + id
        self.AddCreationDate(chapter)
        return chapter

    def AddScene(self,  Chapter,  Title =  None):
        """
            Add a new scene to a chapter.

            @param Chapter Chapter to attach the scene to.
            @param Title Optional title for the scene.
        """
        scene = etree.SubElement(Chapter,  XML_SCENE)
        id = self.GetNextSceneId()
        scene.attrib[XML_ID] = id

        # Scene title.
        if Title is None:  Title = QApplication.translate('New book', 'Scene')
        scene.attrib[XML_TITLE] = Title + ' ' + id

        self.AddCreationDate(scene)
        return scene

    def GetNextChapterId(self):
        return self.GetNextId(XML_CHAPTER_COUNTER);

    def GetNextSceneId(self):
        return self.GetNextId(XML_SCENE_COUNTER)

    def GetNextId(self,  TagName):
        id = self.book.find(TagName)
        # No ID defined yet.
        if id is None:
            root = self.book.getroot()
            id = etree.SubElement(root,  TagName)
            id.text = "0"

        # Increase the counter and write it back.
        n = int(id.text)  + 1
        id.text = str(n)
        return id.text
